<?php
set_time_limit(0);

include_once (dirname(__FILE__).'/config/database.php');
include_once (dirname(__FILE__).'/class/Log.inc');
include_once (dirname(__FILE__).'/class/Mysql/Exception.inc');
include_once (dirname(__FILE__).'/class/Mysql.inc');

define('LOCK_FILE', dirname(__FILE__).'/lock/cronScriptEvery5minute.lock');
define('LOG_LEVEL', 'DEBUG');
define('DingDingUrl',"https://oapi.dingtalk.com/robot/send?access_token=6d215e07cde5353212088a0d2a845edfd51b7fe2e29173ef21aeee67a10d80b4");
define('WarningMsg', "<platformName>平台服务器<serverList>存在异常，请相关人员尽快处理!");
define('RestartFilePath', 'myh5_ad_{platform}_s{sid}');
define('RestartFilePathTest', 'my_{platform}_s000{sid}');


$LogFile = dirname(__FILE__).'/log/cronScriptEvery15minute'.date('Y.m.d').'.log';

$Log = new Zw_Log();
$Log->setCurrLogLevel(LOG_LEVEL);
$Log->setLogFile($LogFile);

$handle = fopen(LOCK_FILE, 'w+');
if(!flock($handle, LOCK_EX|LOCK_NB)){
    $Log->write('进程已经启动，请不要重复启动');
    exit();
}
$warning_time = 300;    //警告时间阈值，单位：秒

//有新平台时，需要增加平台配置
$platformDB = array(
                    1=>array(
                        'name' => 'tw',
                        'db_host' => $gmDatabaseHost,
                        'db_user' => $gmDatabaseUsername,
                        'db_pwd'  => $gmDatabasePassword,
                        'platform_db_name' => 'platform',
                        'file_path' => RestartFilePath
                    ), 
                    2=>array(
                        'name' => '9377',
                        'db_host' => $gmDatabaseHost,
                        'db_user' => $gmDatabaseUsername,
                        'db_pwd'  => $gmDatabasePassword,
                        'platform_db_name' => 'plat_9377',
                        'file_path' => RestartFilePath
                    ),
                    3=>array(
                        'name' => 'xy',
                        'db_host' => $gmDatabaseHost,
                        'db_user' => $gmDatabaseUsername,
                        'db_pwd'  => $gmDatabasePassword,
                        'platform_db_name' => 'plat_xy',
                        'file_path' => RestartFilePath
                    ),
                    99=>array(
                        'name' => 'qd',
                        'db_host' => '39.107.248.181',
                        'db_user' => 'root',
                        'db_pwd'  => 'MGE2ZmNlNjmyh52017.',
                        'platform_db_name' => 'plat_tanwan',
                        'file_path' => RestartFilePathTest
                    )
);

$GmDb = new Zw_Mysql();
$GmDb->setLog($Log);
$GmDb->connect($gmDatabaseHost, $gmDatabaseUsername, $gmDatabasePassword, $gmDatabaseName);
error_log("crontab run server heart script .");
try {
    $sql = "select 
    		        b.operatorFlag, a.areaNum, a.`status` 
            from 
            		t_data_game_area as a, 
            		t_data_operator as b 
            where 
            		a.operatorId = b.operatorId";
    $cfgServerList = $GmDb->getArray($sql);
    
    $sql = "select operatorFlag, sid, UNIX_TIMESTAMP(time) as time  from t_data_server_heart";
    $data = $GmDb->getArray($sql);
    $errorMap = array();
    $now = time();
    foreach ($data as $v) {
        $operatorFlag = $v['operatorFlag'];
        $sid = $v['sid'];
        $time = $v['time'];
        
        //如果游戏区未处于开服状态，则不进行报警
        if(getCfgServerStatus($cfgServerList, $operatorFlag, $sid) < 4) continue;
        //echo $operatorFlag.','.$sid.','.$time.'<br>';
        if($now - $time >= $warning_time)
        {
            //记录异常服务器id
            if(!array_key_exists($operatorFlag, $errorMap))
            {
                $errorMap[$operatorFlag] = array();
            }
            $errorMap[$operatorFlag][] = $sid;
        }
    }
    //echo json_encode($errorMap)."<br>";
    //处理异常
    foreach($errorMap as $key => $value)
    {
        $operatorFlag = $key;
        $serverArr = $value; 
        //echo json_encode($serverArr)."<br>";
        //连接当前平台的数据库
        $dbInfo = $platformDB[$operatorFlag];
        if(empty($dbInfo)) continue;
        //error_log("connect platform db:".$dbInfo['db_host'].', '.$dbInfo['db_user']. ', '.$dbInfo['db_pwd']. ', '.$dbInfo['platform_db_name']);
        $GmDb->connect($dbInfo['db_host'], $dbInfo['db_user'], $dbInfo['db_pwd'], $dbInfo['platform_db_name']);
        //error_log("connect platform db success .");
        $warningMsg = str_replace('<platformName>', $dbInfo['name'], WarningMsg);
        
        //缓存当前平台所有服的配置
        $sql = "select * from cfg_server";
        $allServerInfo = $GmDb->getArray($sql);
        
        //自动将异常服务器状态设置为维护
        $sql = "insert into cfg_server (id) values <serverList> on duplicate key update `status`=2;";
        $serverListStr = "";
        $warningStr = "";
        $restartServerMap = array();    //重启服务器列表
        $restartSidListStr = "";
        foreach($serverArr as $sid)
        {
            $curServer = getServerData($allServerInfo, $sid);
            //echo $sid."<br>";
            if(empty($curServer))
            {
                continue;
            }
            //echo json_encode($curServer)."<br>";
            if($curServer['status'] != 1) continue;
            
            
            $ipAddress = $curServer['ip'];
            if(!array_key_exists($ipAddress, $restartServerMap))
            {
                $restartServerMap[$ipAddress] = "";
            } 
            
            if(empty($serverListStr))
            {
                $serverListStr = '('.$sid.')';
                $warningStr = $sid;
                $restartSidListStr = $sid;
            }else 
            {
                $serverListStr = $serverListStr.', ('.$sid.')'; 
                $warningStr = $warningStr.'、'.$sid;
                $restartSidListStr = $restartSidListStr.','.$sid;
            }
            $restartServerMap[$ipAddress] = $restartSidListStr;
        }
        //echo "serverListStr = ". $serverListStr.'<br>';
        $sql = str_replace('<serverList>', $serverListStr, $sql);
        //echo 'update status sql = '. $sql.'<br>';
        //暂时屏蔽修改服务器状态
        //$GmDb->query($sql);
        
        //通知钉钉
        $warningMsg = str_replace('<serverList>', $warningStr, $warningMsg);
        //echo "warningMsg = ". $warningMsg.'<br>';
        HttpsPost(DingDingUrl, $warningMsg);
        
        $restart_file_path = $dbInfo['file_path'];
        
        //根据当前时间判断是否自动调用重启脚本
        //暂时屏蔽自动重启
//         foreach($restartServerMap as $key => $value)
//         {
//             $file_path = str_replace('{platform}', $dbInfo['name'], $restart_file_path);
//             $url = "http://" . $key . ":8080/serverOptions.php?serverList=".$value . "&file_path=" . $file_path;
//             error_log($url);
//             error_log(file_get_contents($url));
//         }
    }
    
}

catch(Zw_Mysql_Exception $e) {
    $Log->write('数据库错误', 'ERROR');
}
catch(Exception $e) {
    $Log->write('系统错误', 'ERROR');
}

function getServerData($serverInfoList, $sid)
{
    foreach($serverInfoList as $data)
    {
        if(intval($data['id']) == intval($sid))
        {
            return $data;
        }
    }
    return null;
}

function getCfgServerStatus($cfgServerList, $operatorFlag, $sid)
{
    foreach($cfgServerList as $data)
    {
        if($data['operatorFlag'] == $operatorFlag && $data['areaNum'] == $sid)
        {
            return $data['status'];
        }
    }
    return 0;
}

//请求HTTPS
function HttpsPost($url, $content){ // 模拟提交数据函数
    
    $data = array(
        'msgtype'=>'text',
        'text'=>array('content'=>$content, 'atMobiles'=>array()),
        'at'=>array('isAtAll'=>true)
    );
    $data_string = json_encode($data);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
    $data = curl_exec($ch);
    curl_close($ch);
    
    return $data; 
}